package com.aiwu.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.widget.TextViewCompat;

import com.aiwu.library.util.DisplayUtil;

/**
 * 主副屏幕
 */
@SuppressLint("ViewConstructor")
public class ScreenView extends FrameLayout {
    @IntDef({TOP, BOTTOM})
    public @interface Type {
    }

    //主屏幕
    public static final int TOP = 0;
    //副屏幕
    public static final int BOTTOM = 1;

    private ScreenViewGroup mScreenViewGroup;
    @Type
    private int mType;
    private boolean mIsTopScreen;
    private int[] mPresetSizes = new int[]{10, 15, 20, 25};
    private TextView mTextView;
    private View mSpotLeft, mSpotRight, mSpotTop, mSpotBottom;
    //标志线的大小
    private int mSpotSize;
    //标志线的颜色
    private int mSpotColor;

    //拖拽方向
    private int mDragDirection = DIRECTION_NONE;
    public static final int DIRECTION_NONE = 0x0;
    private static final int DIRECTION_TOP = 0x15;
    private static final int DIRECTION_LEFT = 0x16;
    private static final int DIRECTION_BOTTOM = 0x17;
    private static final int DIRECTION_RIGHT = 0x18;
    public static final int DIRECTION_CENTER = 0x19;
    //限制单手指控制
    private boolean mCanDrag = false;

    private int minHeight, minWidth;
    /**
     * 边界X
     */
    private int mTouchAreaMinSize;
    //边界大小跟宽高的比例
    private float mTouchAreaScale = 0.25f;
    private int mTouchAreaSizeX = mTouchAreaMinSize;
    private int mTouchAreaSizeY = mTouchAreaMinSize;

    private int mLastX, mLastY;
    private int mOriLeft, mOriRight, mOriTop, mOriBottom;


    public ScreenView(@NonNull Context context, @NonNull ScreenViewGroup screenViewGroup, @Type int type) {
        super(context);
        mScreenViewGroup = screenViewGroup;
        mType = type;
        mIsTopScreen = type == TOP;
        setBackgroundColor(mIsTopScreen ? Color.parseColor("#800000FF") : Color.parseColor("#80FF0000"));
        mSpotSize = DisplayUtil.dp2px(5);
        mSpotColor = Color.WHITE;

        mTouchAreaMinSize = DisplayUtil.dp2px(15);
        minWidth = DisplayUtil.dp2px(100);
        minHeight = (int) (minWidth / (mIsTopScreen ? ScreenViewGroup.TOP_SCREEN_RATIO : ScreenViewGroup.BOTTOM_SCREEN_RATIO));

        initTextView();
        initSpots();
    }


    private void initTextView() {
        mTextView = new AppCompatTextView(getContext());
        mTextView.setTextColor(Color.WHITE);
        mTextView.setGravity(Gravity.CENTER);
        int dp15 = DisplayUtil.dp2px(15);
        mTextView.setPadding(dp15, dp15, dp15, dp15);
        //自动调整字体大小
        TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(mTextView, mPresetSizes, TypedValue.COMPLEX_UNIT_SP);
        addView(mTextView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    private void initSpots() {
        mSpotLeft = new View(getContext());
        mSpotLeft.setBackgroundColor(mSpotColor);
        mSpotLeft.setVisibility(INVISIBLE);
        LayoutParams lpL = new LayoutParams(mSpotSize, LayoutParams.MATCH_PARENT, Gravity.START);
        addView(mSpotLeft, lpL);

        mSpotRight = new View(getContext());
        mSpotRight.setBackgroundColor(mSpotColor);
        mSpotRight.setVisibility(INVISIBLE);
        LayoutParams lpR = new LayoutParams(mSpotSize, LayoutParams.MATCH_PARENT, Gravity.END);
        addView(mSpotRight, lpR);

        mSpotTop = new View(getContext());
        mSpotTop.setBackgroundColor(mSpotColor);
        mSpotTop.setVisibility(INVISIBLE);
        LayoutParams lpT = new LayoutParams(LayoutParams.MATCH_PARENT, mSpotSize, Gravity.TOP);
        addView(mSpotTop, lpT);

        mSpotBottom = new View(getContext());
        mSpotBottom.setBackgroundColor(mSpotColor);
        mSpotBottom.setVisibility(INVISIBLE);
        LayoutParams lpB = new LayoutParams(LayoutParams.MATCH_PARENT, mSpotSize, Gravity.BOTTOM);
        addView(mSpotBottom, lpB);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        refreshText(w, h);
        mTouchAreaSizeX = (int) Math.max(w * mTouchAreaScale, mTouchAreaMinSize);
        mTouchAreaSizeY = (int) Math.max(h * mTouchAreaScale, mTouchAreaMinSize);
    }

    private void refreshText(int w, int h) {
        String txt = mIsTopScreen ? "主屏幕" : "副屏幕";
        txt += "\n" + w + "x" + h;
        mTextView.setText(txt);
    }

    public int getType() {
        return mType;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                if (event.getPointerId(event.getActionIndex()) == 0) {
                    mCanDrag = true;

                    mOriLeft = getLeft();
                    mOriRight = getRight();
                    mOriTop = getTop();
                    mOriBottom = getBottom();

                    mLastY = (int) event.getRawY();
                    mLastX = (int) event.getRawX();
                    mDragDirection = getDirection((int) event.getX(), (int) event.getY());
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_CANCEL:
                if (event.getPointerId(event.getActionIndex()) == 0) {
                    mCanDrag = false;
                    mDragDirection = DIRECTION_NONE;
                    mSpotLeft.setVisibility(INVISIBLE);
                    mSpotRight.setVisibility(INVISIBLE);
                    mSpotTop.setVisibility(INVISIBLE);
                    mSpotBottom.setVisibility(INVISIBLE);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mCanDrag) {
                    int tempRawX = (int) event.getRawX();
                    int tempRawY = (int) event.getRawY();

                    int dx = tempRawX - mLastX;
                    int dy = tempRawY - mLastY;
                    mLastX = tempRawX;
                    mLastY = tempRawY;

                    switch (mDragDirection) {
                        case DIRECTION_LEFT:
                            left(dx);
                            break;
                        case DIRECTION_RIGHT:
                            right(dx);
                            break;
                        case DIRECTION_BOTTOM:
                            bottom(dy);
                            break;
                        case DIRECTION_TOP:
                            top(dy);
                            break;
                    }
                    setLayoutParams();
                }
                break;
        }
        return true;
    }

    private void setLayoutParams() {
        LayoutParams lp = new LayoutParams(mOriRight - mOriLeft, mOriBottom - mOriTop);
        lp.setMargins(mOriLeft, mOriTop, 0, 0);
        setLayoutParams(lp);
    }

    /**
     * 触摸点为上边缘
     */
    private void top(int dy) {
        mOriTop += dy;
        if (mOriTop < 0) {
            mOriTop = 0;
        }
        if (mOriBottom - mOriTop < minHeight) {
            mOriTop = mOriBottom - minHeight;
        }
        fixWidth();
    }

    /**
     * 触摸点为下边缘
     */
    private void bottom(int dy) {
        mOriBottom += dy;
        int maxHeight = mScreenViewGroup.getHeight();
        if (mOriBottom > maxHeight) {
            mOriBottom = maxHeight;
        }
        if (mOriBottom - mOriTop < minHeight) {
            mOriBottom = minHeight + mOriTop;
        }
        fixWidth();
    }

    /**
     * 触摸点为右边缘
     */
    private void right(int dx) {
        mOriRight += dx;
        int maxWidth = mScreenViewGroup.getWidth();
        if (mOriRight > maxWidth) {
            mOriRight = maxWidth;
        }
        if (mOriRight - mOriLeft < minWidth) {
            mOriRight = mOriLeft + minWidth;
        }
        fixHeight();
    }

    /**
     * 触摸点为左边缘
     */
    private void left(int dx) {
        mOriLeft += dx;
        if (mOriLeft < 0) {
            mOriLeft = 0;
        }
        if (mOriRight - mOriLeft < minWidth) {
            mOriLeft = mOriRight - minWidth;
        }
        fixHeight();
    }

    /**
     * 修正高度
     */
    private void fixHeight() {
        boolean fixed = mIsTopScreen ? mScreenViewGroup.isTopScreenFixedRatio() : mScreenViewGroup.isBottomScreenFixedRatio();
        if (!fixed) {
            return;
        }
        float ratio = mIsTopScreen ? ScreenViewGroup.TOP_SCREEN_RATIO : ScreenViewGroup.BOTTOM_SCREEN_RATIO;
        mOriBottom = mOriTop + (int) ((mOriRight - mOriLeft) / ratio);
        int maxHeight = mScreenViewGroup.getHeight();
        if (mOriBottom > maxHeight) {
            mOriBottom = maxHeight;
            mOriRight = mOriLeft + (int) ((mOriBottom - mOriTop) * ratio);
        }

    }

    /**
     * 修正宽度
     */
    private void fixWidth() {
        boolean fixed = mIsTopScreen ? mScreenViewGroup.isTopScreenFixedRatio() : mScreenViewGroup.isBottomScreenFixedRatio();
        if (!fixed) {
            return;
        }
        float ratio = mIsTopScreen ? ScreenViewGroup.TOP_SCREEN_RATIO : ScreenViewGroup.BOTTOM_SCREEN_RATIO;
        mOriRight = mOriLeft + (int) ((mOriBottom - mOriTop) * ratio);
        int maxWidth = mScreenViewGroup.getWidth();
        if (mOriRight > maxWidth) {
            mOriRight = maxWidth;
            mOriBottom = mOriTop + (int) ((mOriRight - mOriLeft) / ratio);
        }
    }

    private int getDirection(int x, int y) {
        int left = getLeft();
        int right = getRight();
        int bottom = getBottom();
        int top = getTop();
        if (mIsTopScreen && mScreenViewGroup.isTopScreenFixedSize()) {
            return DIRECTION_CENTER;
        } else if (!mIsTopScreen && mScreenViewGroup.isBottomScreenFixedSize()) {
            return DIRECTION_CENTER;
        }
        if (x < mTouchAreaSizeX) {
            mSpotLeft.setVisibility(VISIBLE);
            return DIRECTION_LEFT;
        }
        if (y < mTouchAreaSizeY) {
            mSpotTop.setVisibility(VISIBLE);
            return DIRECTION_TOP;
        }
        if (right - left - x < mTouchAreaSizeX) {
            mSpotRight.setVisibility(VISIBLE);
            return DIRECTION_RIGHT;
        }
        if (bottom - top - y < mTouchAreaSizeY) {
            mSpotBottom.setVisibility(VISIBLE);
            return DIRECTION_BOTTOM;
        }
        return DIRECTION_CENTER;
    }

    public int getDragDirection() {
        return mDragDirection;
    }
}
